#ifndef BANKCLIENT_H
#define BANKCLIENT_H
//在使用Qt的网络类之前，不光要引入头文件（#include <QtNetwork/XXX>），
//还要为工程增加network模块的编译（在QT Creator下修改pro文件：QT += network）
#include <map>
#include <functional>
#include <QtNetwork/QtNetwork>
#include <QtNetwork/QTcpSocket>
#include <QSharedPointer>
//#include "common/singleton.h"
#include "model/bankdataaccess.h"
#include "bankclinetconfig.h"

using namespace std;

//这个类还可以用来读取配置项
class BankClient
{
    //friend class Singleton<BankClient>;
public:
    //执行访问操作
    bool execDataAccess();
    //设置本次请求响应类型
    //类型和具体类的名字是一样的
    //返回false就是表示这个类没有注册
    bool setReqResType(const char * type);
    //设置数据
    void setRawData(const char *key,const char *val);
    //获取数据
    const char *getResRawData(const char *key) const;
    //获取失败的原因数据
    const char *getErrorMsg(void) const;
    //还需要进行一次清理
    void clear(void);
    //配置读取管理，一个是登陆界面增加一个按钮进行配置显示，一个是实现一个类
    //在初始化的时候载入这个配置。关于配置文件这个东西，可以使用观察者的模式，
    //因为有时候会涉及到修改配置的情况，然后点击确定后会马上生效，这里就要通
    //知到使用配置文件的类。
    //观察者模式最好的实践方法就是采取委托，一些类预先将一些方法委托给通知类，
    //然后通知类改变后就调用内部的一个列表进行循环。其实就是使用bind/function方法。
    BankClient(): cliPipe_(new QTcpSocket),errorMsg_("No Error"),buf_(new char[256])
    {
        updateConfig();
        //然后将自己实现的配置更新方法委托给配置管类，在配置有更新的时候进行通知
        BankClinetConfig &bcc = Singleton<BankClinetConfig>::Instance();
        bcc.addDelegate(bind(&BankClient::updateConfig,this));
        //内部有个state函数可以进行连接状态查看，如果是集成到UI里面还可以
        //直接绑定到信号和槽，连接状态会触发不同的信号连接到槽上就可以被处理。
        cliPipe_->connectToHost(host_,port_,QIODevice::ReadWrite);
    }
    ~BankClient() {cliPipe_->close();delete []buf_;}
private:
    void updateConfig()
    {
        //首先从配置管理类中获取数据
        BankClinetConfig &bcc = Singleton<BankClinetConfig>::Instance();
        QString key = "CLIENT-SERVER_IP";
        bcc.getConf(key,host_);
        QString portStr;
        key = "CLIENT-PORT";
        bcc.getConf(key,portStr);
        port_ = portStr.toUInt();
    }
    QString host_;
    quint16 port_;
    BankClient(const BankClient &);
    QSharedPointer<BankDataAccess> bda_;
    QSharedPointer<QTcpSocket> cliPipe_;
    map<QString,QString> rDataMap_;
    //用来装载已经创建的业务数据连接
    map<QString,QSharedPointer<BankDataAccess> > bdaMap_;
    const char *errorMsg_;
    char *buf_;
};

#endif // CLIENT_H
